package com.hontech.bread.ui.fragment

import android.annotation.SuppressLint
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.hontech.bread.R
import com.hontech.bread.app.runWithInit
import com.hontech.bread.device.ResetReplenishEvent
import com.hontech.bread.store.StoreCargo
import com.hontech.bread.store.StoreProduct
import com.hontech.bread.store.setProductImage
import com.hontech.bread.ui.view.MediaPlayer
import com.hontech.bread.utils.AdvManager
import com.hontech.bread.utils.AdvPauseEvent
import com.hontech.bread.utils.AdvReadyEvent
import com.hontech.bread.utils.EmptyEdge
import com.hontech.bread.utils.isBigScreen
import com.hontech.bread.utils.log
import com.hontech.bread.utils.onClick
import com.hontech.bread.utils.priceFormat
import com.hontech.bread.utils.registerEvent
import com.hontech.bread.utils.runOnUiCatchAny
import com.hontech.bread.utils.setClickScaleAnimator
import com.hontech.bread.utils.stringById
import com.hontech.bread.utils.unregister
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.TimeoutCancellationException
import kotlinx.coroutines.withTimeout
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode

class Vend3Fragment : Fragment() {

    private lateinit var mRv: RecyclerView
    private lateinit var mMpTop: MediaPlayer
    private lateinit var mMpBottom: MediaPlayer
    private lateinit var mAdapter: Vend3Adapter

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = if (isBigScreen()) {
            log(stringById(R.string.t1733460848_383))
            inflater.inflate(R.layout.fragment_vend3, null)
        } else {
            log(stringById(R.string.t1733460848_384))
            inflater.inflate(R.layout.fragment_vend3_s, null)
        }
        initUi(view)
        return view
    }

    private fun initUi(view: View) {
        mRv = view.findViewById(R.id.id_vend3_rv)
        mMpTop = view.findViewById(R.id.id_vend3_mp_top)
        mMpBottom = view.findViewById(R.id.id_vend3_mp_bottom)
        mAdapter = Vend3Adapter(mRv)
        mRv.adapter = mAdapter
        mRv.layoutManager =
            LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
        mRv.edgeEffectFactory = EmptyEdge()
    }

    override fun onResume() {
        super.onResume()
        registerEvent(this)
        runOnUiCatchAny {
            runWithInit {
                mAdapter.update()
                if (AdvManager.isReady()) {
                    mMpTop.resume()
                    mMpBottom.resume()
                }
            }
        }
    }

    override fun onPause() {
        super.onPause()
        unregister(this)
        mMpTop.pause()
        mMpBottom.pause()
        mAdapter.pause()
    }

    @Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
    fun onResetReplenishEvent(event: ResetReplenishEvent) {
        runOnUiCatchAny { mAdapter.update() }
    }

    @Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
    fun onAdvReadyEvent(event: AdvReadyEvent) {
        log("on adv ready")
        runOnUiCatchAny {
            if (AdvManager.isReady()) {
                mMpTop.pause()
                mMpBottom.pause()

                mMpTop.resume()
                mMpBottom.resume()
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
    fun onAdvPauseEvent(event: AdvPauseEvent) {
        log("on adv pause")
        runOnUiCatchAny {
            mMpTop.pause()
            mMpBottom.pause()
        }
    }
}

private class Vend3Item(view: View) : RecyclerView.ViewHolder(view) {

    private val image = view.findViewById<ImageView>(R.id.id_item_vend3_image)
    private val tvName = view.findViewById<TextView>(R.id.id_item_vend3_tv_name)
    private val tvPrice = view.findViewById<TextView>(R.id.id_item_vend3_tv_price)
    private val tvNo = view.findViewById<TextView>(R.id.id_item_vend3_tv_no_product)

    init {
        image.setClickScaleAnimator()
    }

    fun setUp(product: StoreProduct, itemClick: suspend (StoreProduct) -> Unit) {
        image.setProductImage(product)
        tvName.text = product.name
        tvPrice.text = priceFormat(product.price.toLong())
        tvName.setTag(R.id.imageId, product.productId)
        runOnUiCatchAny { noEmpty(product) }
        image.onClick {
            try {
                if (noEmpty(product)) {
                    itemClick(product)
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    private suspend fun noEmpty(product: StoreProduct): Boolean {
        val ret = StoreCargo.queryIsNotEmpty(product.productId)
        if (tvName.getTag(R.id.imageId) != product.productId) {
            return false
        }

        if (ret) {
            tvNo.visibility = View.INVISIBLE
        } else {
            tvNo.visibility = View.VISIBLE
        }
        return ret
    }
}

class AnimPauseException : Exception("anim ${stringById(R.string.t1733460848_385)}")

private class Vend3Adapter(private val rv: RecyclerView) : RecyclerView.Adapter<Vend3Item>() {

    private var list = emptyList<StoreProduct>()
    private var animPromise: CompletableDeferred<Unit>? = null
    private var animFlag = false

    fun startAnim() {
        if (animFlag) {
            return
        }
        animFlag = true
        val promise = CompletableDeferred<Unit>()
        animPromise = promise
        runOnUiCatchAny {
            while (animFlag) {
                rv.scrollBy(3, 0)
                try {
                    withTimeout(100) { promise.await() }
                } catch (e: TimeoutCancellationException) {

                }
            }
        }
    }

    fun pause() {
        if (!animFlag) {
            return
        }
        animFlag = false
        val promise = animPromise
        animPromise = null
        promise?.completeExceptionally(AnimPauseException())
    }

    @SuppressLint("NotifyDataSetChanged")
    suspend fun update() {
        pause()

        list = StoreProduct.query()
        notifyDataSetChanged()

        if (list.isNotEmpty()) {
            startAnim()
        }
    }

    override fun getItemCount(): Int {
        if (list.isEmpty()) {
            return 0
        }
        return Int.MAX_VALUE
    }

    override fun onBindViewHolder(holder: Vend3Item, position: Int) {
        val p = position.mod(list.size)
        holder.setUp(list[p], ::itemClick)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Vend3Item {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_vend3, parent, false)
        return Vend3Item(view)
    }

    private suspend fun itemClick(product: StoreProduct) {

    }
}



